#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <vector>
#include <errno.h>
#include <string.h>
#include <string>
#include "LockGuard.hpp"

using namespace std;

#define NUM 3

int ticket = 1000;

class ThreadData
{
public:
    ThreadData(int i, pthread_mutex_t *lock)
    {
        _name = "thread" + to_string(i);
        _lock = lock;
    }

public:
    string _name;
    pthread_mutex_t *_lock;
};

void *ThreadTicket(void *args)
{
    ThreadData *data = static_cast<ThreadData *>(args);
    while (1)
    {
        {
            // pthread_mutex_lock(data->_lock);
            lock_guard lg(data->_lock);
            if (ticket > 0)
            {
                usleep(1000);
                cout << "I'm " << data->_name << " ticket : " << ticket << endl;
                ticket--;
                // pthread_mutex_unlock(data->_lock);
            }
            else
            {
                // pthread_mutex_unlock(data->_lock);
                break;
            }
        }
        usleep(1000);
    }
}

int main()
{
    pthread_mutex_t lock;
    pthread_mutex_init(&lock, nullptr);

    vector<pthread_t> vthd;
    for (int i = 0; i < NUM; i++)
    {
        ThreadData *ptr = new ThreadData(i, &lock);

        pthread_t tid;
        pthread_create(&tid, nullptr, ThreadTicket, ptr);
        vthd.push_back(tid);
        usleep(10000);
    }

    for (auto tid : vthd)
    {
        int n = pthread_join(tid, nullptr);
        if (n != 0)
        {
            cout << strerror(n) << endl;
        }
    }

    return 0;
}